package me.zhengjie.modules.xiao.rest;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.zhengjie.annotation.Log;
import me.zhengjie.annotation.rest.AnonymousPostMapping;
import me.zhengjie.modules.security.service.dto.JwtUserDto;
import me.zhengjie.modules.system.domain.Dept;
import me.zhengjie.modules.system.domain.DictDetail;
import me.zhengjie.modules.system.domain.Job;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.domain.vo.UserQueryCriteria;
import me.zhengjie.modules.system.service.DeptService;
import me.zhengjie.modules.system.service.DictDetailService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.xiao.domain.*;
import me.zhengjie.modules.xiao.domain.dto.*;
import me.zhengjie.modules.xiao.domain.vo.*;
import me.zhengjie.modules.xiao.service.*;
import me.zhengjie.utils.RedisUtils;
import me.zhengjie.utils.SecurityUtils;
import me.zhengjie.utils.VxMsg;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

/**
* @author cg
* @date 2024-06-19
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "首页统计")
@RequestMapping("/api/home")
public class HomeController {

    private static final Logger log = LoggerFactory.getLogger(HomeController.class);
    private final CgCluetableService cgCluetableService;
    private final CgCustomertableService cgCustomertableService;
    private final CgFollowupformService cgFollowupformService;
    private final CgSigningformService cgSigningformService;
    private final CgDesignService cgDesignService;
    private final DeptService deptService;
    private final DictDetailService dictDetailService;
    private final VxMsg vxMsg;
    private final UserService userService;

    @Autowired
    private RedisUtils redisTemplate;

    @GetMapping(value = "/count")
    @Log("首页统计")
    @ApiOperation("首页统计")
    public ResponseEntity<CgHomeCountDTO> count(QueryCountVO queryVO){
        Date date = queryVO.getTime();
        Date thisStartOfWeek=null,thisEndOfWeek=null,lastStartOfWeek=null,lastEndOfWeek =null;
        if("1".equals(queryVO.getStatus())){
             thisStartOfWeek = DateUtil.beginOfDay(date);
             thisEndOfWeek = DateUtil.endOfDay(date);
             lastStartOfWeek = DateUtil.beginOfDay(DateUtil.offsetDay(date,-1));
             lastEndOfWeek = DateUtil.endOfDay(DateUtil.offsetDay(date,-1));
        }else if("2".equals(queryVO.getStatus())){
             thisStartOfWeek = DateUtil.beginOfWeek(date);
             thisEndOfWeek = DateUtil.endOfWeek(date);
             lastStartOfWeek = DateUtil.beginOfWeek(DateUtil.offsetDay(date,-7));
             lastEndOfWeek = DateUtil.endOfWeek(DateUtil.offsetDay(date,-7));
        } else if ("3".equals(queryVO.getStatus())) {
             thisStartOfWeek = DateUtil.beginOfMonth(date);
             thisEndOfWeek = DateUtil.endOfMonth(date);
             lastStartOfWeek = DateUtil.beginOfMonth(DateUtil.offsetDay(date,-30));
             lastEndOfWeek = DateUtil.endOfMonth(DateUtil.offsetDay(date,-30));
        }
        //本次线索
        LambdaQueryWrapper<CgCluetable> clueWrapper = new LambdaQueryWrapper<>();
        clueWrapper.between(CgCluetable::getCreateTime,thisStartOfWeek,thisEndOfWeek);
        clueWrapper.eq(CgCluetable::getCustomerFlag,"1");
        //上次线索
        LambdaQueryWrapper<CgCluetable> lastClueWrapper = new LambdaQueryWrapper<>();
        lastClueWrapper.between(CgCluetable::getCreateTime,lastStartOfWeek,lastEndOfWeek);
        lastClueWrapper.eq(CgCluetable::getCustomerFlag,"1");
        //本次客户
        LambdaQueryWrapper<CgCustomertable> customerWrapper = new LambdaQueryWrapper<>();
        customerWrapper.between(CgCustomertable::getCreateTime,thisStartOfWeek,thisEndOfWeek);
        customerWrapper.eq(CgCustomertable::getCustomerFlag,"1");
        //上次客户
        LambdaQueryWrapper<CgCustomertable> lastCustomerWrapper = new LambdaQueryWrapper<>();
        lastCustomerWrapper.between(CgCustomertable::getCreateTime,lastStartOfWeek,lastEndOfWeek);
        lastCustomerWrapper.eq(CgCustomertable::getCustomerFlag,"1");
        //本次跟踪
        LambdaQueryWrapper<CgFollowupform> followWrapper = new LambdaQueryWrapper<>();
        followWrapper.between(CgFollowupform::getCreateTime,thisStartOfWeek,thisEndOfWeek);
        followWrapper.ne(CgFollowupform::getDeptId,0);
        //上次跟踪
        LambdaQueryWrapper<CgFollowupform> lastFollowWrapper = new LambdaQueryWrapper<>();
        lastFollowWrapper.between(CgFollowupform::getCreateTime,lastStartOfWeek,lastEndOfWeek);
        lastFollowWrapper.ne(CgFollowupform::getDeptId,0);
        //本次签单
        LambdaQueryWrapper<CgSigningform> signWrapper = new LambdaQueryWrapper<>();
        signWrapper.between(CgSigningform::getCreateTime,thisStartOfWeek,thisEndOfWeek);
        signWrapper.ne(CgSigningform::getDeptId,0);
        //上次签单
        LambdaQueryWrapper<CgSigningform> lastSignWrapper = new LambdaQueryWrapper<>();
        lastSignWrapper.between(CgSigningform::getCreateTime,lastStartOfWeek,lastEndOfWeek);
        lastSignWrapper.ne(CgSigningform::getDeptId,0);
        //本次设计
        LambdaQueryWrapper<CgDesign> designWrapper = new LambdaQueryWrapper<>();
        designWrapper.between(CgDesign::getCreateTime,thisStartOfWeek,thisEndOfWeek);
        designWrapper.ne(CgDesign::getDeptId,0);
        //上次设计
        LambdaQueryWrapper<CgDesign> lastDesignWrapper = new LambdaQueryWrapper<>();
        lastDesignWrapper.between(CgDesign::getCreateTime,lastStartOfWeek,lastEndOfWeek);
        lastDesignWrapper.ne(CgDesign::getDeptId,0);


        JwtUserDto userDetails = (JwtUserDto)SecurityUtils.getCurrentUser();
        List<Long> jobs = userDetails.getUser().getJobs().stream().map(Job::getId).collect(Collectors.toList());
        Long deptId = userDetails.getUser().getDept().getId();
        Integer level = userDetails.getLevel();
        Long messCusClue = 0L,messSeaClue=0L,messCusCustomer=0L,messSeaCustomer=0L;
        if(jobs.contains(8L)){
            LambdaQueryWrapper<CgCluetable> messCusClueWrapper = new LambdaQueryWrapper<>();
            messCusClueWrapper.eq(CgCluetable::getCustomerFlag,"1");
            messCusClueWrapper.eq(CgCluetable::getMessageStatus,"1");
            LambdaQueryWrapper<CgCluetable> messSeaClueWrapper = new LambdaQueryWrapper<>();
            messSeaClueWrapper.eq(CgCluetable::getCustomerFlag,"2");
            messSeaClueWrapper.eq(CgCluetable::getMessageStatus,"1");
            LambdaQueryWrapper<CgCustomertable> messCusCustomerWrapper = new LambdaQueryWrapper<>();
            messCusCustomerWrapper.eq(CgCustomertable::getCustomerFlag,"1");
            messCusCustomerWrapper.eq(CgCustomertable::getMessageStatus,"1");
            LambdaQueryWrapper<CgCustomertable> messSeaCustomerWrapper = new LambdaQueryWrapper<>();
            messSeaCustomerWrapper.eq(CgCustomertable::getCustomerFlag,"2");
            messSeaCustomerWrapper.eq(CgCustomertable::getMessageStatus,"1");
            if (level == 3||level == 4) {
                UserQueryCriteria userCriteria = new UserQueryCriteria();
                List<Dept> data = deptService.findByPid(deptId);
                // 然后把子节点的ID都加入到集合中
                userDetails.getDataScopes().get(0);
                List<Long> deptIds = deptService.getDeptChildren(data);
                deptIds.add(deptId);
                deptIds.retainAll(userDetails.getDataScopes());

                clueWrapper.and((wrapper)->{wrapper.in(CgCluetable::getDeptId, deptIds).or().eq(CgCluetable::getCreateBy,userDetails.getUser().getUsername());});
                lastClueWrapper.and((wrapper)->{wrapper.in(CgCluetable::getDeptId, deptIds).or().eq(CgCluetable::getCreateBy,userDetails.getUser().getUsername());});
                customerWrapper.and((wrapper)->{wrapper.in(CgCustomertable::getDeptId, deptIds).or().eq(CgCustomertable::getCreateBy,userDetails.getUser().getUsername());});
                lastCustomerWrapper.and((wrapper)->{wrapper.in(CgCustomertable::getDeptId, deptIds).or().eq(CgCustomertable::getCreateBy,userDetails.getUser().getUsername());});
                followWrapper.and((wrapper)->{wrapper.in(CgFollowupform::getDeptId, deptIds).or().eq(CgFollowupform::getCreateBy,userDetails.getUser().getUsername());});
                lastFollowWrapper.and((wrapper)->{wrapper.in(CgFollowupform::getDeptId, deptIds).or().eq(CgFollowupform::getCreateBy,userDetails.getUser().getUsername());});
                signWrapper.and((wrapper)->{wrapper.in(CgSigningform::getDeptId, deptIds).or().eq(CgSigningform::getCreateBy,userDetails.getUser().getUsername());});
                lastSignWrapper.and((wrapper)->{wrapper.in(CgSigningform::getDeptId, deptIds).or().eq(CgSigningform::getCreateBy,userDetails.getUser().getUsername());});
                designWrapper.and((wrapper)->{wrapper.in(CgDesign::getDeptId, deptIds).or().eq(CgDesign::getCreateBy,userDetails.getUser().getUsername());});
                lastDesignWrapper.and((wrapper)->{wrapper.in(CgDesign::getDeptId, deptIds).or().eq(CgDesign::getCreateBy,userDetails.getUser().getUsername());});

                if (level == 3) {
                    deptIds.add(0L);
                }
                messCusClueWrapper.and((wrapper)->{wrapper.in(CgCluetable::getDeptId, deptIds).or().eq(CgCluetable::getCreateBy,userDetails.getUser().getUsername());});
                messCusCustomerWrapper.and((wrapper)->{wrapper.in(CgCustomertable::getDeptId, deptIds).or().eq(CgCustomertable::getCreateBy,userDetails.getUser().getUsername());});
                messSeaClueWrapper.and((wrapper)->{wrapper.in(CgCluetable::getDeptId, deptIds).or().eq(CgCluetable::getCreateBy,userDetails.getUser().getUsername());});
                messSeaCustomerWrapper.and((wrapper)->{wrapper.in(CgCustomertable::getDeptId, deptIds).or().eq(CgCustomertable::getCreateBy,userDetails.getUser().getUsername());});

            }
            messCusClue = cgCluetableService.count(messCusClueWrapper);
            messCusCustomer = cgCustomertableService.count(messCusCustomerWrapper);
            messSeaClue = cgCluetableService.count(messSeaClueWrapper);
            messSeaCustomer = cgCustomertableService.count(messSeaCustomerWrapper);
        }else{
            clueWrapper.eq(CgCluetable::getCreateBy,userDetails.getUser().getUsername());
            lastClueWrapper.eq(CgCluetable::getCreateBy,userDetails.getUser().getUsername());
            customerWrapper.eq(CgCustomertable::getCreateBy,userDetails.getUser().getUsername());
            lastCustomerWrapper.eq(CgCustomertable::getCreateBy,userDetails.getUser().getUsername());
            followWrapper.eq(CgFollowupform::getCreateBy,userDetails.getUser().getUsername());
            lastFollowWrapper.eq(CgFollowupform::getCreateBy,userDetails.getUser().getUsername());
            signWrapper.eq(CgSigningform::getCreateBy,userDetails.getUser().getUsername());
            lastSignWrapper.eq(CgSigningform::getCreateBy,userDetails.getUser().getUsername());
            designWrapper.eq(CgDesign::getCreateBy,userDetails.getUser().getUsername());
            lastDesignWrapper.eq(CgDesign::getCreateBy,userDetails.getUser().getUsername());
        }
        Long thisClue = cgCluetableService.count(clueWrapper);
        Long lastClue = cgCluetableService.count(lastClueWrapper);
        Long thisCustomer = cgCustomertableService.count(customerWrapper);
        Long lastCustomer = cgCustomertableService.count(lastCustomerWrapper);
        Long thisfollow = cgFollowupformService.count(followWrapper);
        Long lastfollow = cgFollowupformService.count(lastFollowWrapper);
        Long thisSign = cgSigningformService.count(signWrapper);
        Long lastSign = cgSigningformService.count(lastSignWrapper);
        Long thisDesign = cgDesignService.count(designWrapper);
        Long lastDesign = cgDesignService.count(lastDesignWrapper);

        CgHomeCountDTO cgHomeCountDTO = new CgHomeCountDTO(thisClue,lastClue,thisCustomer,lastCustomer,thisfollow,lastfollow,thisSign,lastSign,thisDesign,lastDesign,
        messCusClue,messSeaClue,messCusCustomer,messSeaCustomer);
        return new ResponseEntity<>(cgHomeCountDTO,HttpStatus.OK);
    }

    @GetMapping(value = "/strip")
    @Log("条形图")
    @ApiOperation("条形图")
    public ResponseEntity<List<CgHomeLineDTO>> strip(QueryStripVO queryVO){
        JwtUserDto userDetails = (JwtUserDto)SecurityUtils.getCurrentUser();
        Integer level = userDetails.getLevel();
        List<Long> deptIds = new ArrayList<>();
        if (userDetails.getUser().getIsAdmin() ||level == 1||level == 2) {
        }else if (level == 3||level == 4) {
            Long deptId = userDetails.getUser().getDept().getId();
            List<Dept> data = deptService.findByPid(deptId);
            // 然后把子节点的ID都加入到集合中
            userDetails.getDataScopes().get(0);
            deptIds = deptService.getDeptChildren(data);
            deptIds.add(deptId);
            deptIds.retainAll(userDetails.getDataScopes());
            deptIds.add(0L);
        }else{
            deptIds.add(0L);
        }
        queryVO.getDeptIds().addAll(deptIds);
        return new ResponseEntity<>(cgCluetableService.queryStrip(queryVO),HttpStatus.OK);
    }

    @GetMapping(value = "/pie")
    @Log("饼图")
    @ApiOperation("饼图")
    public ResponseEntity<List<CgHomeLineDTO>> pie(){
        CgDesignQueryCriteria queryVO = new CgDesignQueryCriteria();
        JwtUserDto userDetails = (JwtUserDto)SecurityUtils.getCurrentUser();
        Integer level = userDetails.getLevel();
        List<Long> deptIds = new ArrayList<>();
        if (userDetails.getUser().getIsAdmin() ||level == 1||level == 2) {
        }else if (level == 3||level == 4) {
            Long deptId = userDetails.getUser().getDept().getId();
            List<Dept> data = deptService.findByPid(deptId);
            // 然后把子节点的ID都加入到集合中
            userDetails.getDataScopes().get(0);
            deptIds = deptService.getDeptChildren(data);
            deptIds.add(deptId);
            deptIds.retainAll(userDetails.getDataScopes());
            deptIds.add(0L);
        }else{
            deptIds.add(0L);
        }
        queryVO.getDeptIds().addAll(deptIds);
        List<CgDesign> list = cgDesignService.queryAll(queryVO);
        DateTime date = DateTime.now();
        DateTime threeTime = DateUtil.offsetDay(date,3);
        DateTime sevenTime = DateUtil.offsetDay(date,7);
        DateTime fifteenTime = DateUtil.offsetDay(date,15);
        DateTime thirtyTime = DateUtil.offsetDay(date,30);
        Long three = list.stream().filter(cgDesign -> cgDesign.getStatus().equals("1") && cgDesign.getCycleEnd().before(date) && threeTime.before(cgDesign.getCycleEnd())).count();
        Long seven = list.stream().filter(cgDesign -> cgDesign.getStatus().equals("1") && cgDesign.getCycleEnd().before(threeTime) && sevenTime.before(cgDesign.getCycleEnd())).count();
        Long fifteen = list.stream().filter(cgDesign -> cgDesign.getStatus().equals("1") && cgDesign.getCycleEnd().before(sevenTime) && fifteenTime.before(cgDesign.getCycleEnd())).count();
        Long thirty = list.stream().filter(cgDesign -> cgDesign.getStatus().equals("1") && cgDesign.getCycleEnd().before(fifteenTime) && threeTime.before(cgDesign.getCycleEnd())).count();
        Long thirtyOut = list.stream().filter(cgDesign -> cgDesign.getStatus().equals("1") && cgDesign.getCycleEnd().before(thirtyTime)).count();

        List<CgHomeLineDTO> listDTO = new ArrayList<>();

        listDTO.add(new CgHomeLineDTO("超期 3 天内",three));
        listDTO.add(new CgHomeLineDTO("超期 7 天内",seven));
        listDTO.add(new CgHomeLineDTO("超期 15 天内",fifteen));
        listDTO.add(new CgHomeLineDTO("超期 30 天内",thirty));
        listDTO.add(new CgHomeLineDTO("超期 30 天外",thirtyOut));
        return new ResponseEntity<>(listDTO,HttpStatus.OK);
    }

    @GetMapping(value = "/line")
    @Log("折线图")
    @ApiOperation("折线图")
    public ResponseEntity<List<CgHomeLineDTO>> line(QueryLineVO queryVO){
        JwtUserDto userDetails = (JwtUserDto)SecurityUtils.getCurrentUser();
        Integer level = userDetails.getLevel();
        List<Long> deptIds = new ArrayList<>();
        if (userDetails.getUser().getIsAdmin() ||level == 1||level == 2) {
        }else if (level == 3||level == 4) {
            Long deptId = userDetails.getUser().getDept().getId();
            List<Dept> data = deptService.findByPid(deptId);
            // 然后把子节点的ID都加入到集合中
            userDetails.getDataScopes().get(0);
            deptIds = deptService.getDeptChildren(data);
            deptIds.add(deptId);
            deptIds.retainAll(userDetails.getDataScopes());
            deptIds.add(0L);

        }else{
            deptIds.add(0L);
        }
        queryVO.getDeptIds().addAll(deptIds);
        return new ResponseEntity<>(cgCluetableService.queryLine(queryVO),HttpStatus.OK);
    }

    @GetMapping(value = "/report")
    @Log("报表")
    @ApiOperation("报表")
    public ResponseEntity<List<Map<String,Object>>> report(QueryReportVO queryVO){
        JwtUserDto userDetails = (JwtUserDto)SecurityUtils.getCurrentUser();
        Integer level = userDetails.getLevel();
        List<Long> deptIds = new ArrayList<>();
        if (userDetails.getUser().getIsAdmin() ||level == 1||level == 2) {
        }else if (level == 3||level == 4) {
            Long deptId = userDetails.getUser().getDept().getId();
            List<Dept> data = deptService.findByPid(deptId);
            // 然后把子节点的ID都加入到集合中
            userDetails.getDataScopes().get(0);
            deptIds = deptService.getDeptChildren(data);
            deptIds.add(deptId);
            deptIds.retainAll(userDetails.getDataScopes());
            //deptIds.add(0L);
            queryVO.setDeptIds(deptIds);
        }else{
            queryVO.getCreateBys().add(userDetails.getUser().getUsername());
        }
        return new ResponseEntity<>(cgCluetableService.queryReport(queryVO),HttpStatus.OK);
    }

    @PostMapping("/excelExport")
    @Log("导出资源模版")
    @ApiOperation(value = "导出资源模版", notes = "导出资源模版")
    public void excelExport(HttpServletResponse response, @RequestBody CgExcelVo vo) throws IOException {
        String dateStr = DateUtil.format(new Date(),"yyyy-MM-dd");
        CgDateVo dateVo = new CgDateVo(DateUtil.beginOfDay( DateUtil.parse(vo.getStartDay(),"yyyy-MM-dd")),DateUtil.endOfDay( DateUtil.parse(vo.getEndDay(),"yyyy-MM-dd")));
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		InputStream in = resolver.getResource("excel/first.xlsx").getInputStream();
		XSSFWorkbook wb = new XSSFWorkbook(in);

        QueryWrapper<Dept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.eq("sub_count","0");
        List<Dept> listDept = deptService.getBaseMapper().selectList(deptQueryWrapper);

		XSSFSheet sheet1 =  wb.getSheet("线索量排名");
        sheet1.getRow(1).getCell(0).setCellValue("周度汇总 统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet1.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        List<ExcelClueDTO>  listClue = cgCluetableService.excelClue(dateVo);
		for (int i = 0; i < listClue.size(); i++) {
            ExcelClueDTO entity = listClue.get(i);
            Row row1 = sheet1.getRow(i + 4);
            row1.getCell(0).setCellValue(entity.getDeptName());
            row1.getCell(1).setCellValue(entity.getCreateDeptName());
            row1.getCell(2).setCellValue(entity.getNickName());
            row1.getCell(3).setCellValue(entity.getTotal());
        }

        XSSFSheet sheet2 =  wb.getSheet("设计量排名");
        sheet2.getRow(1).getCell(0).setCellValue("周度汇总 统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet2.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        List<ExcelDesignDTO>  listDesign = cgCluetableService.excelDesign(dateVo);
		for (int i = 0; i < listDesign.size(); i++) {
            ExcelDesignDTO entity = listDesign.get(i);
            Row row2 = sheet2.getRow(i + 4);
            row2.getCell(0).setCellValue(entity.getDeptName());
            row2.getCell(1).setCellValue(entity.getCreateDeptName());
            row2.getCell(2).setCellValue(entity.getNickName());
            row2.getCell(3).setCellValue(entity.getTotal());
            row2.getCell(4).setCellValue(entity.getAmount());
        }

        XSSFSheet sheet3 =  wb.getSheet("业绩额排名");
        sheet3.getRow(1).getCell(0).setCellValue("周度汇总 统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet3.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        List<ExcelSignDTO>  listSign = cgCluetableService.excelSign(dateVo);
		for (int i = 0; i < listSign.size(); i++) {
            ExcelSignDTO entity = listSign.get(i);
            Row row3 = sheet3.getRow(i + 4);
            row3.getCell(0).setCellValue(entity.getDeptName());
            row3.getCell(1).setCellValue(entity.getCreateDeptName());
            row3.getCell(2).setCellValue(entity.getNickName());
            row3.getCell(3).setCellValue(entity.getTotal());
            row3.getCell(4).setCellValue(entity.getAmount());
        }


        XSSFSheet sheet4 =  wb.getSheet("业务员推送数量排名");
        sheet4.getRow(1).getCell(0).setCellValue("周度汇总 统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet4.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        List<ExcelBusDTO>  listBus = cgCluetableService.excelBus(dateVo);
		for (int i = 0; i < listBus.size(); i++) {
            ExcelBusDTO entity = listBus.get(i);
            Row row4 = sheet4.getRow(i + 4);
            row4.getCell(0).setCellValue(entity.getDeptName());
            row4.getCell(1).setCellValue(entity.getNickName());
            row4.getCell(2).setCellValue(entity.getTotal());
        }

        XSSFSheet sheet5 =  wb.getSheet("数据明细");
        sheet5.getRow(1).getCell(0).setCellValue("周度汇总 统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet5.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        List<ExceDetailDTO>  listDetail = cgCluetableService.excelDetail(dateVo);
		for (int i = 0; i < listDetail.size(); i++) {
            ExceDetailDTO entity = listDetail.get(i);
            Row row5 = sheet5.getRow(i + 4);
            row5.getCell(0).setCellValue(entity.getNickName());
            row5.getCell(1).setCellValue(entity.getCreateDeptName());
            row5.getCell(2).setCellValue(entity.getDeptName());
            row5.getCell(3).setCellValue(entity.getTotal());
            row5.getCell(4).setCellValue(entity.getDesignTotal());
            row5.getCell(5).setCellValue(entity.getAmount());
        }

		XSSFSheet sheet6 =  wb.getSheet("统计表");
        sheet6.getRow(1).getCell(0).setCellValue("周度汇总 统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet6.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        List<ExcelTotalDTO>  listTotal = cgCluetableService.excelTotal(dateVo);
		for (int i = 0; i < listTotal.size(); i++) {
            ExcelTotalDTO entity = listTotal.get(i);
            Row row6 = sheet6.getRow(i + 4);
            row6.getCell(0).setCellValue(entity.getDeptName());
            row6.getCell(1).setCellValue(entity.getTotal());
            row6.getCell(2).setCellValue(entity.getDesignTotal());
            row6.getCell(3).setCellValue(entity.getAmount());
        }
		response.setContentType("application/octet-stream");
		String encodedFileName = URLEncoder.encode("统计", "UTF-8");
		response.setHeader("Content-Disposition", "attachment;filename="+encodedFileName+".xlsx");
		wb.write(response.getOutputStream());
		wb.close();
    }

    @PostMapping("/excelExport2")
    @Log("导出资源模版2")
    @ApiOperation(value = "导出资源模版2", notes = "导出资源模版2")
    public void excelExport2(HttpServletResponse response, @RequestBody CgExcelVo vo) throws IOException, InterruptedException {
        String dateStr = DateUtil.format(new Date(),"yyyy-MM-dd");
        CgDateVo dateVo = new CgDateVo(DateUtil.beginOfDay( DateUtil.parse(vo.getStartDay(),"yyyy-MM-dd")),DateUtil.endOfDay( DateUtil.parse(vo.getEndDay(),"yyyy-MM-dd")));
        List<Date> dateList = new ArrayList<>();
        dateList.add(dateVo.getStartTime());
        dateList.add(dateVo.getEndTime());

        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        System.setProperty("javax.xml.accessExternalSchema", "all");
        System.setProperty("javax.xml.accessExternalDTD", "all");

		InputStream in = resolver.getResource("excel/second.xlsx").getInputStream();
		XSSFWorkbook wb = new XSSFWorkbook(in);

        CountDownLatch latch = ThreadUtil.newCountDownLatch(4);
        qiandan(wb,dateStr, vo, dateList, latch);
        kehu(wb,dateStr, vo, dateList, latch);
        xiansuo(wb,dateStr, vo, dateList, latch);
        gonghaixiansuo(wb,dateStr, vo, dateList, latch);
        latch.await();

		response.setContentType("application/octet-stream");
		String encodedFileName = URLEncoder.encode("列表", "UTF-8");
		response.setHeader("Content-Disposition", "attachment;filename="+encodedFileName+".xlsx");
		wb.write(response.getOutputStream());
		wb.close();
    }

    private  void qiandan(XSSFWorkbook wb, String dateStr, CgExcelVo vo, List<Date> dateList, CountDownLatch latch) {
        XSSFSheet sheet2 =  wb.getSheet("签单信息统计");
        sheet2.getRow(1).getCell(0).setCellValue("统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet2.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);

        CgSigningformQueryCriteria signCriteria = new CgSigningformQueryCriteria();
        signCriteria.setCreateTimeList(dateList);
        List<CgSignExcelDTO>  listSign = cgSigningformService.queryExcel(signCriteria);

        CellStyle style = wb.createCellStyle();
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setAlignment(HorizontalAlignment.CENTER);

		for (int i = 0; i < listSign.size(); i++) {
            CgSignExcelDTO entity = listSign.get(i);
            Row row = sheet2.createRow(i + 4);

            Cell cell = row.createCell(0);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getProvinceDept());

            cell = row.createCell(1);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCityDept());

            cell = row.createCell(2);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getAreaDept());

            cell = row.createCell(3);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getNickName());

            cell = row.createCell(4);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCreateDeptName());

            cell = row.createCell(5);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCustomerAddress());

            cell = row.createCell(6);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getSignTel());

            cell = row.createCell(7);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getSignCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(8);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getDesignCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(9);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getSignDate(), "yyyy/MM/dd"));

            cell = row.createCell(10);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getSignAmount());
        }
        latch.countDown();
    }

    private  void kehu(XSSFWorkbook wb, String dateStr, CgExcelVo vo, List<Date> dateList, CountDownLatch latch) {
       XSSFSheet sheet3 =  wb.getSheet("客户明细");
        sheet3.getRow(1).getCell(0).setCellValue("统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet3.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        CgCustomertableQueryCriteria criteria = new CgCustomertableQueryCriteria();
        criteria.setCustomerFlag("1");
        criteria.setCreateTimeList(dateList);

        CellStyle style = wb.createCellStyle();
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setAlignment(HorizontalAlignment.CENTER);

        List<CgCusExcelDTO> listCustomer = cgCustomertableService.queryExcel(criteria);
        for (int i = 0; i < listCustomer.size(); i++) {
            CgCusExcelDTO entity = listCustomer.get(i);
            Row row = sheet3.createRow(i + 4);

            Cell cell = row.createCell(0);
            cell.setCellStyle(style);
            cell.setCellValue(i+1);

            cell = row.createCell(1);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getNickName());

            cell = row.createCell(2);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getAreaDept());

            cell = row.createCell(3);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCityDept());

            cell = row.createCell(4);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getProvinceDept());

            cell = row.createCell(5);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(6);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCustomerTel());

            cell = row.createCell(7);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCustomerAddress());

            cell = row.createCell(8);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getDeptName());

            cell = row.createCell(9);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getFollowStatus());

            cell = row.createCell(10);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getDesignCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(11);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getTotalAmount());

            cell = row.createCell(12);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getSignDate(), "yyyy/MM/dd"));

            cell = row.createCell(13);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getSignAmount());
        }
        latch.countDown();
    }

    private  void xiansuo(XSSFWorkbook wb, String dateStr, CgExcelVo vo, List<Date> dateList, CountDownLatch latch){
        XSSFSheet sheet1 =  wb.getSheet("线索明细");
        sheet1.getRow(1).getCell(0).setCellValue("统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet1.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);

        CgCluetableQueryCriteria criteriaCluetable = new CgCluetableQueryCriteria();
        criteriaCluetable.setCreateTimeList(dateList);
        criteriaCluetable.setCustomerFlag("1");


        CellStyle style = wb.createCellStyle();
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setAlignment(HorizontalAlignment.CENTER);

        List<CgCusExcelDTO> listCluetable = cgCluetableService.queryExcel(criteriaCluetable);
        for (int i = 0; i < listCluetable.size(); i++) {
            CgCusExcelDTO entity = listCluetable.get(i);
            Row row = sheet1.createRow(i + 4);
            Cell cell = row.createCell(0);
            cell.setCellStyle(style);
            cell.setCellValue(i+1);

            cell = row.createCell(1);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getNickName());

            cell = row.createCell(2);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getAreaDept());

            cell = row.createCell(3);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCityDept());

            cell = row.createCell(4);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getProvinceDept());

            cell = row.createCell(5);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(6);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCustomerTel());

            cell = row.createCell(7);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCustomerAddress());

            cell = row.createCell(8);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getDeptName());

            cell = row.createCell(9);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getFollowStatus());

            cell = row.createCell(10);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getDesignCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(11);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getTotalAmount());

            cell = row.createCell(12);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getSignDate(), "yyyy/MM/dd"));

            cell = row.createCell(13);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getSignAmount());
        }
        latch.countDown();
    }

    private void gonghaixiansuo(XSSFWorkbook wb, String dateStr, CgExcelVo vo, List<Date> dateList, CountDownLatch latch){
        XSSFSheet sheet4 =  wb.getSheet("公海线索明细");
        sheet4.getRow(1).getCell(0).setCellValue("统计日期："+vo.getStartDay()+"至"+vo.getEndDay());
        sheet4.getRow(2).getCell(0).setCellValue("报表生成时间："+dateStr);
        CgCluetableQueryCriteria criteriaCluetable1 = new CgCluetableQueryCriteria();
        criteriaCluetable1.setCreateTimeList(dateList);
        criteriaCluetable1.setCustomerFlag("2");

        CellStyle style = wb.createCellStyle();
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setAlignment(HorizontalAlignment.CENTER);

        List<CgCusExcelDTO> listCluetable1 = cgCluetableService.queryExcel(criteriaCluetable1);
        for (int i = 0; i < listCluetable1.size(); i++) {
            CgCusExcelDTO entity = listCluetable1.get(i);
            Row row = sheet4.createRow(i + 4);
            Cell cell = row.createCell(0);
            cell.setCellStyle(style);
            cell.setCellValue(i+1);

            cell = row.createCell(1);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getNickName());

            cell = row.createCell(2);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getAreaDept());

            cell = row.createCell(3);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCityDept());

            cell = row.createCell(4);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getProvinceDept());

            cell = row.createCell(5);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(6);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCustomerTel());

            cell = row.createCell(7);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getCustomerAddress());

            cell = row.createCell(8);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getDeptName());

            cell = row.createCell(9);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getFollowStatus());

            cell = row.createCell(10);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getDesignCreateTime(), "yyyy/MM/dd"));

            cell = row.createCell(11);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getTotalAmount());

            cell = row.createCell(12);
            cell.setCellStyle(style);
            cell.setCellValue(DateUtil.format(entity.getSignDate(), "yyyy/MM/dd"));

            cell = row.createCell(13);
            cell.setCellStyle(style);
            cell.setCellValue(entity.getSignAmount());
        }
        latch.countDown();
    }
    @GetMapping(value = "/getNotice")
    @Log("getNotice")
    @ApiOperation("getNotice")
    public ResponseEntity<Object> getNotice(){
        DictDetail dictDetail = dictDetailService.getById(22);
        return new ResponseEntity<>(dictDetail, HttpStatus.OK);
    }

    @Log("修改字典详情")
    @ApiOperation("修改字典详情")
    @GetMapping(value = "/updateNotice")
    public ResponseEntity<Object> updateDictDetail(String status){
        DictDetail dictDetail = dictDetailService.getById(22);
        dictDetail.setValue(status);
        dictDetailService.update(dictDetail);
        return new ResponseEntity<>(HttpStatus.OK);
    }
    @GetMapping(value = "/test")
    @Log("test")
    @ApiOperation("test")
    public ResponseEntity<Object> test(String userName){
        vxMsg.sendCustomerMsg(userName,1,1,"aa",DateUtil.formatDate(new Date()));
        return new ResponseEntity<>(null, HttpStatus.OK);
    }

    @AnonymousPostMapping(value = "/test1")
    @Log("test1")
    @ApiOperation("test1")
    public ResponseEntity<Object> test1(){
        log.info("------------------------");
        return new ResponseEntity<>("aaa", HttpStatus.OK);
    }

    public static void main(String[] args) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Date date = DateUtil.parse("2024-06-17","yyyy-MM-dd");
        System.out.println(weekDays[DateUtil.dayOfWeek(date)-1]);

        System.out.println(DateUtil.endOfMonth(new Date()).dayOfMonth());
        System.out.println(DateUtil.endOfYear(new Date()).month()+1);
    }
}